package com.geek.jdbc.pool.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @Desc TODO
 * @Author
 * @Date 2025/11/17
 *
 * 如何使用C3P0数据库连接池
 * 1.导入c3p0-0.9.1.2.jar的jar包 -> Add as Library
 * 2.在src下，新建c3p0-config.xml配置文件
 * 3.com.mchange.v2.c3p0.ComboPooledDataSource  核心类，实现DataSource接口规范
 * 4.构造方法
 *   4.1 public ComboPooledDataSource() 使用c3p0-config.xml配置文件中，默认节点 <default-config>
 *   4.2 public ComboPooledDataSource(String configName) 使用c3p0-config.xml配置文件中，指定名称的节点 <named-config name="mysql">
 * 5.常用API方法
 *   5.1 获取连接  getConnection()
 *   5.2 归还连接  close()
 *
 * 总结
 * 本质上使用的是 NewProxyConnection 连接对象
 * C3P0 重写close()，不会直接释放连接对象，而是将连接对象归还至连接池中； 一并做释放资源 PreparedStatement 、 ResultSet
 */
public class  C3P0Demo {

    public static void main(String[] args) {
        //无参构造方法，对应默认配置节点
        ComboPooledDataSource pool = new ComboPooledDataSource();
        //有参构造方法，对应指定配置文件名称
        //ComboPooledDataSource pool = new ComboPooledDataSource("mysql");

        Connection conn1 = null;
        try {
            //获取连接
            conn1 = pool.getConnection();
            //com.mchange.v2.c3p0.impl.NewProxyConnection@71bc1ae4
            System.out.println("conn1 = "+conn1);

            //指定女生ID查询信息
            PreparedStatement ppst = conn1.prepareStatement("select name from girl where id = ?");
            ppst.setInt(1 , 2);
            ResultSet rs = ppst.executeQuery();
            while (rs.next()) {
                System.out.println("2号女生的信息 = "+rs.getString("name"));
            }

            //测试提前归还连接对象，再次尝试获取连接对象，最终是可以再次获取连接对象的
            /*if(conn1!=null){
                try {
                    conn1.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }*/

            //再次尝试获取连接对象  抛出异常An attempt by a client to checkout a Connection has timed out.
            //提前归还  com.mchange.v2.c3p0.impl.NewProxyConnection@7d4793a8
            Connection conn2 = pool.getConnection();
            System.out.println("conn2 = "+conn2);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if(conn1!=null){
                try {
                    //C3P0 重写close()，不会直接释放连接对象，而是将连接对象归还至连接池中
                    //PreparedStatement 、 ResultSet 有一并做释放资源
                    conn1.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        //归还连接
    }

}
